This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.
This version of beta calculation is used for the theoretical method/results of the paper. For reference: the last update was Dec 2018 for an R notebook. This R notebook is an updated and more sophisticated version.
Constants used are listed at the start of this script.
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
source("inspack.R")
Loading required package: tidyverse
[37m-- [1mAttaching packages[22m --------------------------------------- tidyverse 1.2.1 --[39m
[37m[32mv[37m [34mggplot2[37m 3.2.1 [32mv[37m [34mpurrr [37m 0.3.3
[32mv[37m [34mtibble [37m 2.1.3 [32mv[37m [34mdplyr [37m 0.8.3
[32mv[37m [34mtidyr [37m 1.0.0 [32mv[37m [34mstringr[37m 1.4.0
[32mv[37m [34mreadr [37m 1.3.1 [32mv[37m [34mforcats[37m 0.4.0[39m
[37m-- [1mConflicts[22m ------------------------------------------ tidyverse_conflicts() --
[31mx[37m [34mdplyr[37m::[32mfilter()[37m masks [34mstats[37m::filter()
[31mx[37m [34mdplyr[37m::[32mlag()[37m masks [34mstats[37m::lag()[39m
Loading required package: plyr
-----------------------------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
-----------------------------------------------------------------------------------------------------
Attaching package: 㤼㸱plyr㤼㸲
The following objects are masked from 㤼㸱package:dplyr㤼㸲:
arrange, count, desc, failwith, id, mutate, rename, summarise, summarize
The following object is masked from 㤼㸱package:purrr㤼㸲:
compact
Loading required package: grid
Loading required package: gridExtra
Attaching package: 㤼㸱gridExtra㤼㸲
The following object is masked from 㤼㸱package:dplyr㤼㸲:
combine
Loading required package: plotly
Registered S3 method overwritten by 'data.table':
method from
print.data.table
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
Attaching package: 㤼㸱plotly㤼㸲
The following objects are masked from 㤼㸱package:plyr㤼㸲:
arrange, mutate, rename, summarise
The following object is masked from 㤼㸱package:ggplot2㤼㸲:
last_plot
The following object is masked from 㤼㸱package:stats㤼㸲:
filter
The following object is masked from 㤼㸱package:graphics㤼㸲:
layout
Loading required package: ggthemes
Loading required package: viridis
Loading required package: viridisLite
Loading required package: data.table
data.table 1.12.6 using 6 threads (see ?getDTthreads). Latest news: r-datatable.com
Attaching package: 㤼㸱data.table㤼㸲
The following objects are masked from 㤼㸱package:dplyr㤼㸲:
between, first, last
The following object is masked from 㤼㸱package:purrr㤼㸲:
transpose
Loading required package: Rmisc
Loading required package: lattice

#values needed
K= 1.38064852*(10)^-23 #m2 kg/ s2 K boltzmann constant
mu= 1.126*(10)^-3 #kg/m s dynamic viscosity in 18C
v= 1.099*(10)^-6 #m2/s kinematic viscosity in 18C
Reh_calc= 2.3E-6 #in m radius Ehux
Reh_naked= 1.8E-6 #in m radius Ehux
Reh_lith = 1.5E-6 #in m radius
Rehv= 90*(10)^-9 #in m radius virus
Temp = 18+273.15 #temp in kelvin, here assuming 18C
Den_OcM = 1.05 #g/cm3 density organic cell matter
Den_CH2O= 1.025 #g/cm3 density seawater at 18C
CcNum <- 0.9*((10)^3)
NcNum <- 0.1*((10)^3)
ViNum <- (CcNum+NcNum)*10
LiNum <- CcNum*50
Calculating for Brownian motion
#Brownian motion (BM)
#1. make a data frame
BM <- data.frame (group=as.factor(c("Nc", "Cc", "Li")), rad= c(1.8E-6, 2.3E-6, 1.5E-6))
#2. calculate beta (beta)
BM$beta_BM <- ((2*(K*(10)^4)*Temp*(((BM$rad+Rehv)*100)^2))/((3*mu*10)*(BM$rad*Rehv*1e4)))*86400 #cm3/d
# go back to this later
#3. calculate encounters (E)
BM$E_BM <- BM$beta_BM*ViNum
BM
Differential settling
#Differential settling (DS)
#1. read in PIC data
library(readr) #always use readr not baseR
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
PIC <- read_csv("Postdoc-R/CSV Files/PIC.csv")
Parsed with column specification:
cols(
Strain = [31mcol_character()[39m,
Replicate = [32mcol_double()[39m,
TC = [32mcol_double()[39m,
AC = [32mcol_double()[39m,
Cellcount = [32mcol_double()[39m
)
PIC$Strain <- as.factor(PIC$Strain)
PIC$Replicate <- as.factor(PIC$Replicate)
#2. calculate PIC for cell
PIC$PIC <- PIC$TC-PIC$AC
PIC$PICpercell <- (PIC$PIC/PIC$Cellcount)*(10)^-3#in g
PIC$PICpercellpg <- PIC$PICpercell*1e12
ggplotly(ggplot(data=PIC, aes(x=Strain, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2) +theme_Publication())
#3a. calculate density of cells (den_cell)
PIC <- mutate(PIC, group = ifelse(PICpercellpg < 4 , "naked", "calcified"))
ggplotly(ggplot(data=PIC, aes(x=group, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2, aes(color=Strain))+ theme_Publication())
plotly.js does not (yet) support horizontal legend items
You can track progress here:
https://github.com/plotly/plotly.js/issues/53
PIC <- mutate(PIC, rad = ifelse(group == "naked" , 1.8E-6, 2.3E-6)) #in m
PIC$volume <- (4/3)*pi*(PIC$rad*100)^3 #in cm3
PIC$Den_cell <- PIC$PICpercell/PIC$volume #g/cm3
PIC$Den_celltotal <- PIC$Den_cell+Den_OcM
ggplotly(ggplot(data=PIC, aes(x=Strain, y=Den_celltotal, color=group)) + geom_boxplot()+geom_point(size=2)
+theme_Publication())
plotly.js does not (yet) support horizontal legend items
You can track progress here:
https://github.com/plotly/plotly.js/issues/53
#some strains that are "naked" have PIC<2. I chose to ignore this since in the lm model I do not use
#strain as a factor, rather data is treated as a whole (e.g., no grouping)
ggplotly(ggplot(data=PIC, aes(x=Strain, y=Denlith, color=group)) + geom_boxplot()+geom_point(size=2)
+theme_Publication())
plotly.js does not (yet) support horizontal legend items
You can track progress here:
https://github.com/plotly/plotly.js/issues/53
#4. calculate sinking velocity of cells,liths, and viruses
PIC$SinkVel <- ((2*((PIC$rad*100)^2)*(981)*(PIC$Den_celltotal-Den_CH2O))/(9*(mu*10)))*864 #meter per day
PIC$SinkVel_lith <- ((2*((Reh_lith*100)^2)*(981)*(PIC$Denlith-Den_CH2O))/(9*(mu*10)))*864 #meter per day
Ehv_SinkVel <- ((2*((Rehv*100)^2)*(981)*(Den_CH2O-Den_CH2O))/(9*(mu*10)))*864 #equals to 0
#g is converted to per day, 864 is the one that converts cm/s to m/day
#plot sinking velocity vs calcification
ggplot(data=PIC, aes(x=PICpercellpg, y=SinkVel, color=Strain, shape=group2)) + geom_point(size=5)+theme_Publication()+
labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC pg"~cell^-1)) +
theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank())

ggplot(data=PIC %>% filter (group=="calcified"), aes(x=perlithpg, y=SinkVel_lith, color=Strain, shape=group2)) +
geom_point(size=5)+theme_Publication()+
labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC pg"~lith^-1)) +
theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank())

#5. calculate betas for DS
PIC$beta_DS <-(pi*(((PIC$rad+Rehv)*100)^2)*(abs((PIC$SinkVel-Ehv_SinkVel)/864)))*86400 #in encounters cm3/day
PIC$beta_DS_lith <- (pi*(((Reh_lith+Rehv)*100)^2)*(abs((PIC$SinkVel_lith-Ehv_SinkVel)/864)))*86400 #in encounters cm3/day
ggplot(data=PIC, aes(x=PICpercellpg, y=beta_DS, color=Strain, shape=group2)) + geom_point(size=5)+theme_Publication()+
labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~cell^-1)) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank())

ggplot(data=PIC %>% filter (group=="calcified"), aes(x=perlithpg, y=beta_DS_lith, color=Strain, shape=group2)) + geom_point(size=5)+theme_Publication()+
labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~lith^-1)) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank())


#7. summaries
library(plyr)
summary_DS <- ddply(PIC, .(Strain), summarize, PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg),
Den_celltotal = mean (Den_celltotal),SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith),
beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS_bygroup2 <- ddply(PIC, .(group2), summarize, PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg),
Den_celltotal = mean (Den_celltotal), SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith),
beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS_bygroup <- ddply(PIC %>% filter (! group2 %in% c("naked/calcified uncertain")) , .(group),
summarize, PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg),
Den_celltotal = mean (Den_celltotal), SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith),
beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS
summary_DS_bygroup2
summary_DS_bygroup
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
require(openxlsx)
Loading required package: openxlsx
write.xlsx(summary_DS, file = "Postdoc-R/Exported Tables/summary_DS.xlsx")
Note: zip::zip() is deprecated, please use zip::zipr() instead
write.xlsx(summary_DS_bygroup, file = "Postdoc-R/Exported Tables/summary_DS_bygroup.xlsx")
write.xlsx(summary_DS_bygroup2, file = "Postdoc-R/Exported Tables/summary_DS_bygroup2.xlsx")
#8. regressions
#8a. PIC and beta_DS of cells
PIC_beta_reg <- lm (beta_DS ~ PICpercellpg, data=PIC)
summary(PIC_beta_reg)
Call:
lm(formula = beta_DS ~ PICpercellpg, data = PIC)
Residuals:
Min 1Q Median 3Q Max
-2.465e-07 -6.697e-08 -3.387e-09 7.849e-08 1.981e-07
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.074e-07 2.634e-08 4.076 0.00025 ***
PICpercellpg 3.305e-07 3.096e-09 106.755 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1.196e-07 on 35 degrees of freedom
Multiple R-squared: 0.9969, Adjusted R-squared: 0.9969
F-statistic: 1.14e+04 on 1 and 35 DF, p-value: < 2.2e-16
plot(residuals.lm(PIC_beta_reg))

coef(PIC_beta_reg)
(Intercept) PICpercellpg
1.073674e-07 3.305428e-07
cor(PIC$PICpercellpg, PIC$beta_DS)
[1] 0.998468
#8b. PIC and beta_DS of liths
PIClith_beta_reg <- lm (beta_DS_lith ~ perlithpg, data=PIC)
summary(PIClith_beta_reg)
Call:
lm(formula = beta_DS_lith ~ perlithpg, data = PIC)
Residuals:
Min 1Q Median 3Q Max
-7.907e-07 -8.410e-08 9.626e-08 1.819e-07 8.903e-07
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.844e-06 7.623e-08 37.31 < 2e-16 ***
perlithpg 1.343e-06 1.255e-07 10.71 1.39e-12 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 3.463e-07 on 35 degrees of freedom
Multiple R-squared: 0.766, Adjusted R-squared: 0.7593
F-statistic: 114.6 on 1 and 35 DF, p-value: 1.386e-12
plot(residuals.lm(PIClith_beta_reg))

coef(PIClith_beta_reg)
(Intercept) perlithpg
2.844387e-06 1.343038e-06
cor(PIC$perlithpg, PIC$beta_DS_lith)
[1] 0.8752268
#8c. for PIC of liths depending on PICs of cells
PIC_lith_reg <- lm (perlithpg~PICpercellpg, data=PIC)
summary(PIC_lith_reg)
essentially perfect fit: summary may be unreliable
Call:
lm(formula = perlithpg ~ PICpercellpg, data = PIC)
Residuals:
Min 1Q Median 3Q Max
-1.139e-16 -4.974e-17 -2.739e-17 -7.870e-18 7.920e-16
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.460e-16 3.223e-17 4.530e+00 6.58e-05 ***
PICpercellpg 7.143e-02 3.789e-18 1.885e+16 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1.464e-16 on 35 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 3.553e+32 on 1 and 35 DF, p-value: < 2.2e-16
plot(residuals.lm(PIC_lith_reg))

coef(PIC_lith_reg)
(Intercept) PICpercellpg
1.460156e-16 7.142857e-02
cor(PIC$perlithpg, PIC$SinkVel_lith)
[1] 0.8794049
#8d other regressions
PIC_Den_celltotal_reg <- lm(Den_celltotal ~ PICpercellpg, data=PIC)
PIC_SinkVel_reg <- lm (SinkVel ~ PICpercellpg, data=PIC)
PIC_Denlith_reg <- lm(Denlith ~ perlithpg, data=PIC)
PIC_SinkVel_lith_reg <- lm (SinkVel_lith ~ PICpercellpg, data=PIC)
plot(residuals.lm(PIC_Den_celltotal_reg))

plot(residuals.lm(PIC_SinkVel_reg))

plot(residuals.lm(PIC_Denlith_reg))

plot(residuals.lm(PIC_SinkVel_lith_reg))

#9. make a prediction based on PIC values
#9a. for cells
require(truncnorm)
Loading required package: truncnorm
require(Rmisc)
summary(PIC$PICpercellpg)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-0.4144 1.0497 2.9736 5.6575 7.0660 20.1442
summarySE(data=PIC, measurevar="PICpercellpg")
#make new dataframe
PIC_newdata <- as.data.frame(rtruncnorm(n=10000, a=-0.4, b=20.2, mean=5.7, sd=6.5))
#rename column. rename function in plyr
library(plyr)
PIC_newdata <- rename (PIC_newdata, c ("rtruncnorm(n = 10000, a = -0.4, b = 20.2, mean = 5.7, sd = 6.5)" =
"PICpercellpg"))
Error: All arguments must be named
[90mCall `rlang::last_error()` to see a backtrace.[39m
PIC_newdata$group2 <- case_when(
PIC_newdata$PICpercellpg <2 ~ "naked",
PIC_newdata$PICpercellpg >2 & PIC_newdata$PICpercellpg < 4 ~ "naked/calcified uncertain",
PIC_newdata$PICpercellpg >4 & PIC_newdata$PICpercellpg < 10 ~ "moderately calcified",
PIC_newdata$PICpercellpg >10 ~ "heavily calcified",
TRUE ~ as.character(PIC_newdata$PICpercellpg)
)
PIC_newdata$group2 <- factor (PIC_newdata$group2,levels= c("naked", "naked/calcified uncertain",
"moderately calcified", "heavily calcified"),
labels = c("naked", "naked/calcified uncertain",
"moderately calcified", "heavily calcified"))
ggplotly(ggplot(data=PIC_newdata, aes(x=group2, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2)
+theme_Publication())
#make new predictions. density, sinkvel, beta are predicted based on PIC. for liths, PIC are first predicted and then the other parameters.
PIC_newdata$perlithpg <- predict(PIC_lith_reg, data.frame(PIC_newdata))
PIC_newdata$Den_celltotal <- predict (PIC_Den_celltotal_reg, data.frame (PIC_newdata))
PIC_newdata$SinkVel <- predict (PIC_SinkVel_reg, data.frame (PIC_newdata))
PIC_newdata$Denlith <- predict (PIC_Denlith_reg, data.frame (PIC_newdata))
PIC_newdata$SinkVel_lith <- predict (PIC_SinkVel_lith_reg, data.frame (PIC_newdata))
PIC_newdata$beta_DS <- predict (PIC_beta_reg, data.frame(PIC_newdata))
PIC_newdata$beta_DS_lith <- predict (PIClith_beta_reg, data.frame(PIC_newdata))
ggplot(data=PIC_newdata %>% filter (!(group %in% c("naked/calcified uncertain"))), aes(x=PICpercellpg, y=beta_DS, color= group2)) + geom_point(size=5)+theme_Publication()+
labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~cell^-1)) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank())

ggplot(data=PIC_newdata, aes(x=perlithpg, y=beta_DS_lith, color= group2)) + geom_point(size=5)+theme_Publication()+
labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~lith^-1)) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank())

ggplot(data=PIC_newdata %>% filter (group %in% c("calcified")), aes(x=perlithpg, y=beta_DS_lith, color= group2)) + geom_point(size=5)+theme_Publication()+
labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~lith^-1)) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank())

#10. calculate encounters based on newdata
#change to trim
PIC_newdata.trim$E_DS <- (PIC_newdata.trim$beta_DS*virnum) #E calculated with Virus for cell
PIC_newdata.trim$E_DS_lith <- (PIC_newdata.trim$beta_DS_lith*virnum) #E calculated with Virus for cell
ggplot(data=PIC_newdata.trim, aes(x=PICpercellpg, y=E_DS)) +geom_point(size=5, aes(color=group2)) +
theme_Publication() + geom_smooth() +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
labs(y = expression("viral encounters " ~ day^-1~cell^-1), x = expression("PIC pg"~cell^-1)) +
theme(legend.title = element_blank())

summary_DS_bygroup2_pred <-ddply(PIC, .(group2), summarize, PICpercellpg=mean(PICpercellpg),
perlithpg = mean(perlithpg), Den_celltotal = mean (Den_celltotal),
SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith),
beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS_bygroup2_pred
#remove naked/calcified uncertain
summary_DS_bygroup_pred <-ddply(PIC_newdata.trim, .(group), summarize, PICpercellpg=mean(PICpercellpg),
perlithpg = mean(perlithpg), Den_celltotal = mean (Den_celltotal),
SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith),
beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS_bygroup_pred
ggplot(data=PIC_newdata.trim, aes(x=PICpercellpg, y=E_DS)) +geom_point(size=5, aes(color=group2)) +
theme_Publication() + geom_smooth() +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
labs(y = expression("viral encounters " ~ day^-1~cell^-1), x = expression("PIC pg"~cell^-1)) +
theme(legend.title = element_blank())

ggplot(data=PIC_newdata.trim, aes(x=perlithpg, y=E_DS)) +geom_point(size=5, aes(color=group2)) +
theme_Publication() + geom_smooth() +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
labs(y = expression("viral encounters " ~ day^-1~lith^-1), x = expression("PIC pg"~lith^-1)) +
theme(legend.title = element_blank())

setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
write.xlsx(summary_DS_bygroup_pred, file = "Postdoc-R/Exported Tables/summary_DS_bygroup_pred.xlsx")
#arrange the summary
DS_pred <- data.frame (group=as.factor(c("Nc", "Cc", "Li")), rad= c(1.8E-6, 2.3E-6, 1.5E-6),
PIC= c(0.8296382, 9.6032644, 0.48016322), Den= c(1.087058, 1.248226, 1.210054),
SinkVel = c(0.03377913, 0.18832330, 0.04836724),
beta_DS = c(3.815983e-07, 3.281657e-06, 2.728417e-07))
DS <- data.frame (group=as.factor(c("Nc", "Cc", "Li")), rad= c(1.8E-6, 2.3E-6, 1.5E-6),
PIC = c(0.6979222, 11.4840119, 0.57420059), Den = c(1.078569, 1.275331, 1.241400),
SinkVel = c (0.02903311, 0.2215147, 0.05656002),
beta_DS = c(3.258119e-07, 3.975103e-06, 3.190575e-07))
DS
DS_pred
Turbulence
#Turbulence
#1. make new dataframe
#disrate is cm2/s3
#make data frame
disrate <- rep_len (c (1 %o% 10^(seq(-8,-2, 0.5))), length.out=39)
calc <- rep_len(c("Cc"), length.out=13)
naked <- rep_len(c("Nc"), length.out=13)
lith <- rep_len(c("Li"), length.out=13)
group <- c(naked, calc, lith)
turb <- as.data.frame(cbind(disrate, group))
turb$rad <- case_when(
turb$group =="Nc" ~ 1.8E-6,
turb$group =="Cc" ~ 2.3E-6,
turb$group =="Li" ~ 1.25E-6,
TRUE ~ as.numeric(turb$group)
)
turb$disrate <- as.numeric(as.character(turb$disrate))
#2. calculate beta and encounters
turb$beta_turb <- (4.2*pi*((turb$disrate/(v*100^2))^0.5)*(((turb$rad+Rehv)*100)^3))*86400
turb$E_turb <- (turb$beta_turb*virnum) #E calculated with virus only
turb$group <- factor (turb$group,levels= c("Nc", "Cc", "Li"), labels = c("Nc", "Cc", "Li"))
ggplot(data = turb, aes(x = disrate, y = beta_turb, color=group)) + geom_point(size =5) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
scale_x_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
annotation_logticks() +
theme_Publication() +
labs(y = expression(beta~("predicted encounters " ~cm^3~day^-1)),
x = expression("dissipation rate "~(m^2~s^-3))) +
theme(legend.title = element_blank())

ggplot(data = turb, aes(x = disrate, y = E_turb, color=group)) + geom_point(size =5) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
scale_x_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
annotation_logticks()+
theme_Publication()+
labs(y = expression("viral encounters " ~ cm^-3~day^-1),x = expression("dissipation rate "~(m^2~s^-3))) +
theme(legend.title = element_blank())

melt all data and make a table with all
all <- Reduce(function(x,y) merge(x,y,by="group",all=TRUE) ,
list(BM %>% select (group, beta_BM), DS_pred %>% select (group, beta_DS),
turb %>% select (group, disrate, beta_turb)))
all$beta_all <- all$beta_BM + all$beta_DS + all$beta_turb
all$E_all_low <- all$beta_all*(10^4)
all$E_all_high <- all$beta_all*(10^6)
all$group <- factor (all$group,levels= c("Nc", "Cc", "Li"), labels = c("Nc", "Cc", "Li"))
#plotting
ggplot(data=all, aes(x=disrate,y = E_all_low, color=group)) +
geom_line(size=1, position=position_jitter(w=0.02, h=0), aes(linetype="10^3"))+
geom_line(data = all, aes(y= E_all_high, color=group, linetype="10^5")) +
scale_y_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
scale_x_log10(
breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
labels = scales::trans_format("log10", scales::math_format(10^.x))) +
annotation_logticks()+
theme_Publication() +
theme(legend.title = element_blank(), legend.key.width=unit(1,"cm"))+
labs(y = expression("viral encounters " ~day^-1~cell^-1), x = expression("dissipation rate "~(m^2~s^-3))) +
theme(legend.title = element_blank())

LS0tDQp0aXRsZTogImJldGEga2VybmVsIGZvciBwYXBlciINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIA0KDQpUaGlzIHZlcnNpb24gb2YgYmV0YSBjYWxjdWxhdGlvbiBpcyB1c2VkIGZvciB0aGUgdGhlb3JldGljYWwgbWV0aG9kL3Jlc3VsdHMgb2YgdGhlIHBhcGVyLiBGb3IgcmVmZXJlbmNlOiB0aGUgbGFzdCB1cGRhdGUgd2FzIERlYyAyMDE4IGZvciBhbiBSIG5vdGVib29rLiBUaGlzIFIgbm90ZWJvb2sgaXMgYW4gdXBkYXRlZCBhbmQgbW9yZSBzb3BoaXN0aWNhdGVkIHZlcnNpb24uIA0KDQpDb25zdGFudHMgdXNlZCBhcmUgbGlzdGVkIGF0IHRoZSBzdGFydCBvZiB0aGlzIHNjcmlwdC4NCg0KYGBge3J9DQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCnNvdXJjZSgiaW5zcGFjay5SIikNCiN2YWx1ZXMgbmVlZGVkIA0KDQpLPSAxLjM4MDY0ODUyKigxMCleLTIzICNtMiBrZy8gczIgSyBib2x0em1hbm4gY29uc3RhbnQNCm11PSAxLjEyNiooMTApXi0zICNrZy9tIHMgZHluYW1pYyB2aXNjb3NpdHkgaW4gMThDDQp2PSAxLjA5OSooMTApXi02ICNtMi9zIGtpbmVtYXRpYyB2aXNjb3NpdHkgaW4gMThDDQpSZWhfY2FsYz0gMi4zRS02ICNpbiBtIHJhZGl1cyBFaHV4DQpSZWhfbmFrZWQ9IDEuOEUtNiAjaW4gbSByYWRpdXMgRWh1eA0KUmVoX2xpdGggPSAxLjVFLTYgI2luIG0gcmFkaXVzDQpSZWh2PSA5MCooMTApXi05ICNpbiBtIHJhZGl1cyB2aXJ1cw0KVGVtcCA9IDE4KzI3My4xNSAjdGVtcCBpbiBrZWx2aW4sIGhlcmUgYXNzdW1pbmcgMThDDQpEZW5fT2NNID0gMS4wNSAjZy9jbTMgZGVuc2l0eSBvcmdhbmljIGNlbGwgbWF0dGVyDQpEZW5fQ0gyTz0gMS4wMjUgI2cvY20zIGRlbnNpdHkgc2Vhd2F0ZXIgYXQgMThDDQpDY051bSA8LSAwLjkqKCgxMCleMykNCk5jTnVtIDwtIDAuMSooKDEwKV4zKQ0KVmlOdW0gPC0gKENjTnVtK05jTnVtKSoxMA0KTGlOdW0gPC0gQ2NOdW0qNTANCmBgYA0KDQpDYWxjdWxhdGluZyBmb3IgQnJvd25pYW4gbW90aW9uDQoNCmBgYHtyfQ0KI0Jyb3duaWFuIG1vdGlvbiAoQk0pDQojMS4gbWFrZSBhIGRhdGEgZnJhbWUNCkJNIDwtIGRhdGEuZnJhbWUgKGdyb3VwPWFzLmZhY3RvcihjKCJOYyIsICJDYyIsICJMaSIpKSwgcmFkPSBjKDEuOEUtNiwgMi4zRS02LCAxLjVFLTYpKSANCg0KIzIuIGNhbGN1bGF0ZSBiZXRhIChiZXRhKQ0KQk0kYmV0YV9CTSA8LSAoKDIqKEsqKDEwKV40KSpUZW1wKigoKEJNJHJhZCtSZWh2KSoxMDApXjIpKS8oKDMqbXUqMTApKihCTSRyYWQqUmVodioxZTQpKSkqODY0MDAgI2NtMy9kDQoNCiMgZ28gYmFjayB0byB0aGlzIGxhdGVyDQojMy4gY2FsY3VsYXRlIGVuY291bnRlcnMgKEUpDQpCTSRFX0JNIDwtIEJNJGJldGFfQk0qVmlOdW0NCg0KQk0NCmBgYA0KDQpEaWZmZXJlbnRpYWwgc2V0dGxpbmcNCmBgYHtyfQ0KI0RpZmZlcmVudGlhbCBzZXR0bGluZyAoRFMpDQojMS4gcmVhZCBpbiBQSUMgZGF0YQ0KbGlicmFyeShyZWFkcikgI2Fsd2F5cyB1c2UgcmVhZHIgbm90IGJhc2VSDQoNCnNldHdkKCJEOi9SIHByb2dyYW0iKQ0KUElDIDwtIHJlYWRfY3N2KCJQb3N0ZG9jLVIvQ1NWIEZpbGVzL1BJQy5jc3YiKQ0KDQpQSUMkU3RyYWluIDwtIGFzLmZhY3RvcihQSUMkU3RyYWluKQ0KUElDJFJlcGxpY2F0ZSA8LSBhcy5mYWN0b3IoUElDJFJlcGxpY2F0ZSkNCg0KIzIuIGNhbGN1bGF0ZSBQSUMgZm9yIGNlbGwNClBJQyRQSUMgPC0gUElDJFRDLVBJQyRBQw0KUElDJFBJQ3BlcmNlbGwgPC0gKFBJQyRQSUMvUElDJENlbGxjb3VudCkqKDEwKV4tMyNpbiBnDQpQSUMkUElDcGVyY2VsbHBnIDwtIFBJQyRQSUNwZXJjZWxsKjFlMTINCg0KZ2dwbG90bHkoZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1TdHJhaW4sIHk9UElDcGVyY2VsbHBnKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgK3RoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCiMzYS4gY2FsY3VsYXRlIGRlbnNpdHkgb2YgY2VsbHMgKGRlbl9jZWxsKQ0KUElDIDwtIG11dGF0ZShQSUMsIGdyb3VwID0gaWZlbHNlKFBJQ3BlcmNlbGxwZyA8IDQgLCAibmFrZWQiLCAiY2FsY2lmaWVkIikpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9Z3JvdXAsIHk9UElDcGVyY2VsbHBnKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MiwgYWVzKGNvbG9yPVN0cmFpbikpKyB0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQpQSUMgPC0gbXV0YXRlKFBJQywgcmFkID0gaWZlbHNlKGdyb3VwID09ICJuYWtlZCIgLCAxLjhFLTYsICAyLjNFLTYpKSAjaW4gbQ0KDQpQSUMkdm9sdW1lIDwtICg0LzMpKnBpKihQSUMkcmFkKjEwMCleMyAjaW4gY20zDQpQSUMkRGVuX2NlbGwgPC0gUElDJFBJQ3BlcmNlbGwvUElDJHZvbHVtZSAjZy9jbTMNClBJQyREZW5fY2VsbHRvdGFsIDwtIFBJQyREZW5fY2VsbCtEZW5fT2NNDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PURlbl9jZWxsdG90YWwsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgDQogICAgICAgICArdGhlbWVfUHVibGljYXRpb24oKSkNCg0KI3NvbWUgc3RyYWlucyB0aGF0IGFyZSAibmFrZWQiIGhhdmUgUElDPDIuIEkgY2hvc2UgdG8gaWdub3JlIHRoaXMgc2luY2UgaW4gdGhlIGxtIG1vZGVsIEkgZG8gbm90IHVzZQ0KI3N0cmFpbiBhcyBhIGZhY3RvciwgcmF0aGVyIGRhdGEgaXMgdHJlYXRlZCBhcyBhIHdob2xlIChlLmcuLCBubyBncm91cGluZykNCg0KDQpgYGANCmBgYHtyfQ0KI2Fzc3VtZSBncm91cGluZw0KUElDJGdyb3VwMiA8LSBjYXNlX3doZW4oDQogIFBJQyRQSUNwZXJjZWxscGcgPDIgIH4gIm5ha2VkIiwNCiAgUElDJFBJQ3BlcmNlbGxwZyA+MiAmIFBJQyRQSUNwZXJjZWxscGcgPCA0IH4gIm5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4iLA0KICBQSUMkUElDcGVyY2VsbHBnID40ICYgUElDJFBJQ3BlcmNlbGxwZyA8IDEwIH4gIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwNCiAgUElDJFBJQ3BlcmNlbGxwZyA+MTAgfiAiaGVhdmlseSBjYWxjaWZpZWQiLCANCiAgVFJVRSB+IGFzLmNoYXJhY3RlcihQSUMkUElDcGVyY2VsbHBnKQ0KKQ0KDQpQSUMkZ3JvdXAyIDwtIGZhY3RvciAoUElDJGdyb3VwMixsZXZlbHM9IGMoIm5ha2VkIiwgIm5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtb2RlcmF0ZWx5IGNhbGNpZmllZCIsICJoZWF2aWx5IGNhbGNpZmllZCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIm5ha2VkIiwgIm5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwgImhlYXZpbHkgY2FsY2lmaWVkIikpDQoNCiMzYi4gY2FsY3VsYXRlIFBJQyBhbmQgZGVuc2l0eSBmb3IgbGl0aA0KUElDJHBlcmxpdGggPC0gUElDJFBJQ3BlcmNlbGwvMTQgI2luIGcsIGFzc3VtaW5nIDIwIGxpdGhzIGF0dGFjaGVkDQpQSUMkcGVybGl0aHBnIDwtIFBJQyRwZXJsaXRoKjFlMTIgI2luIHBnDQpQSUMkRGVubGl0aCA8LSBjYXNlX3doZW4oDQogIFBJQyRncm91cDIgPT0gIm5ha2VkIiAgfiAwLCANCiAgUElDJGdyb3VwMiA9PSAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIgfiAwLA0KICBQSUMkZ3JvdXAyID09ICJtb2RlcmF0ZWx5IGNhbGNpZmllZCIgfiAyLA0KICBQSUMkZ3JvdXAyID09ICJoZWF2aWx5IGNhbGNpZmllZCIgfiAyLjYpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PURlbmxpdGgsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgDQogICAgICAgICArdGhlbWVfUHVibGljYXRpb24oKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIzQuIGNhbGN1bGF0ZSBzaW5raW5nIHZlbG9jaXR5IG9mIGNlbGxzLGxpdGhzLCBhbmQgdmlydXNlcw0KUElDJFNpbmtWZWwgPC0gKCgyKigoUElDJHJhZCoxMDApXjIpKig5ODEpKihQSUMkRGVuX2NlbGx0b3RhbC1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgI21ldGVyIHBlciBkYXkNClBJQyRTaW5rVmVsX2xpdGggPC0gKCgyKigoUmVoX2xpdGgqMTAwKV4yKSooOTgxKSooUElDJERlbmxpdGgtRGVuX0NIMk8pKS8oOSoobXUqMTApKSkqODY0ICNtZXRlciBwZXIgZGF5DQpFaHZfU2lua1ZlbCA8LSAoKDIqKChSZWh2KjEwMCleMikqKDk4MSkqKERlbl9DSDJPLURlbl9DSDJPKSkvKDkqKG11KjEwKSkpKjg2NCAgI2VxdWFscyB0byAwDQojZyBpcyBjb252ZXJ0ZWQgdG8gcGVyIGRheSwgODY0IGlzIHRoZSBvbmUgdGhhdCBjb252ZXJ0cyBjbS9zIHRvIG0vZGF5DQojcGxvdCBzaW5raW5nIHZlbG9jaXR5IHZzIGNhbGNpZmljYXRpb24NCg0KDQpnZ3Bsb3QoZGF0YT1QSUMsIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1TaW5rVmVsLCBjb2xvcj1TdHJhaW4sIHNoYXBlPWdyb3VwMikpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogICAgbGFicyh5ID0gZXhwcmVzc2lvbigiU2lua2luZyB2ZWxvY2l0eSJ+KCJtIn5kYXleLTEpKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+Y2VsbF4tMSkpICsNCiAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSANCg0KZ2dwbG90KGRhdGE9UElDICU+JSBmaWx0ZXIgKGdyb3VwPT0iY2FsY2lmaWVkIiksIGFlcyh4PXBlcmxpdGhwZywgeT1TaW5rVmVsX2xpdGgsIGNvbG9yPVN0cmFpbiwgc2hhcGU9Z3JvdXAyKSkgKyANCiAgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oIlNpbmtpbmcgdmVsb2NpdHkifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmxpdGheLTEpKSArDQogICAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgDQoNCg0KYGBgDQpgYGB7cn0NCiM1LiBjYWxjdWxhdGUgYmV0YXMgZm9yIERTDQpQSUMkYmV0YV9EUyA8LShwaSooKChQSUMkcmFkK1JlaHYpKjEwMCleMikqKGFicygoUElDJFNpbmtWZWwtRWh2X1NpbmtWZWwpLzg2NCkpKSo4NjQwMCAjaW4gZW5jb3VudGVycyBjbTMvZGF5DQpQSUMkYmV0YV9EU19saXRoIDwtIChwaSooKChSZWhfbGl0aCtSZWh2KSoxMDApXjIpKihhYnMoKFBJQyRTaW5rVmVsX2xpdGgtRWh2X1NpbmtWZWwpLzg2NCkpKSo4NjQwMCAjaW4gZW5jb3VudGVycyBjbTMvZGF5DQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9UElDcGVyY2VsbHBnLCB5PWJldGFfRFMsIGNvbG9yPVN0cmFpbiwgIHNoYXBlPWdyb3VwMikpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oYmV0YX4oIkVuY291bnRlcnMifmNtXjN+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmNlbGxeLTEpKSAgKw0Kc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKSsNCiAgICAgIHRoZW1lKGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsIGxlZ2VuZC5ib3ggPSAidmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpIA0KDQpnZ3Bsb3QoZGF0YT1QSUMgJT4lIGZpbHRlciAoZ3JvdXA9PSJjYWxjaWZpZWQiKSwgYWVzKHg9cGVybGl0aHBnLCB5PWJldGFfRFNfbGl0aCwgY29sb3I9U3RyYWluLCBzaGFwZT1ncm91cDIpKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKGJldGF+KCJFbmNvdW50ZXJzIn5jbV4zfmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIHBnIn5saXRoXi0xKSkgICsNCnNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikrDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSANCg0KYGBgDQoNCg0KYGBge3J9DQojNi4gY2FsY3VsYXRlIGVuY291bnRlcnMNClBJQyRFX0RTIDwtIChQSUMkYmV0YV9EUypWaU51bSkgI0UgY2FsY3VsYXRlZCB3aXRoIFZpcnVzIGZvciBjZWxsDQpQSUMkRV9EU19saXRoIDwtIChQSUMkYmV0YV9EU19saXRoKlZpTnVtKSAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgZm9yIGxpdGgNCg0KZ2dwbG90bHkoZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9bG9nMTAoRV9EUykpKSArZ2VvbV9wb2ludChzaXplPTUsIGFlcyhzaGFwZT1ncm91cDIsIGNvbG9yPVN0cmFpbikpICsNCiAgICB0aGVtZV9QdWJsaWNhdGlvbigpICsgZ2VvbV9zbW9vdGgoKSkNCiNyZW1vdmUgc3RyYWlucyA2MjEsIDYyMywgNjI1DQpQSUMgPC0gUElDICU+JSBmaWx0ZXIgKCEgU3RyYWluICVpbiUgYygiNjIxIiwgIjYyMyIsICI2NTUiKSkNCg0KZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9RV9EUywgY29sb3I9U3RyYWluLCAgc2hhcGU9Z3JvdXAyKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKSArDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oInZpcmFsIGVuY291bnRlcnMgIiB+IGRheV4tMX5jZWxsXi0xKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+Y2VsbF4tMSkpDQoNCmdncGxvdChkYXRhPVBJQyAlPiUgZmlsdGVyIChncm91cCA9PSJjYWxjaWZpZWQiKSwgYWVzKHg9cGVybGl0aHBnLCB5PUVfRFNfbGl0aCwgY29sb3I9U3RyYWluLCAgc2hhcGU9Z3JvdXAyKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKSArDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oInZpcmFsIGVuY291bnRlcnMgIiB+IGRheV4tMX5jZWxsXi0xKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+bGl0aF4tMSkpDQpgYGANCg0KYGBge3J9DQojNy4gc3VtbWFyaWVzDQpsaWJyYXJ5KHBseXIpDQpzdW1tYXJ5X0RTIDwtIGRkcGx5KFBJQywgLihTdHJhaW4pLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCBwZXJsaXRocGcgPSBtZWFuKHBlcmxpdGhwZyksIA0KICAgICAgICAgICAgICAgICAgICBEZW5fY2VsbHRvdGFsID0gbWVhbiAoRGVuX2NlbGx0b3RhbCksU2lua1ZlbD1tZWFuKFNpbmtWZWwpLGJldGFfRFM9bWVhbihiZXRhX0RTKSwgRV9EUz0gbWVhbihFX0RTKSwNCiAgICAgICAgICAgICAgICAgICAgRGVubGl0aCA9IG1lYW4gKERlbmxpdGgpLCBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgDQogICAgICAgICAgICAgICAgICAgIGJldGFfRFNfbGl0aD1tZWFuIChiZXRhX0RTX2xpdGgpLCBFX0RTX2xpdGg9bWVhbiAoRV9EU19saXRoKSkNCnN1bW1hcnlfRFNfYnlncm91cDIgPC0gZGRwbHkoUElDLCAuKGdyb3VwMiksIHN1bW1hcml6ZSwgIFBJQ3BlcmNlbGxwZz1tZWFuKFBJQ3BlcmNlbGxwZyksIHBlcmxpdGhwZyA9IG1lYW4ocGVybGl0aHBnKSwgDQogICAgICAgICAgICAgICAgICAgIERlbl9jZWxsdG90YWwgPSBtZWFuIChEZW5fY2VsbHRvdGFsKSwgU2lua1ZlbD1tZWFuKFNpbmtWZWwpLGJldGFfRFM9bWVhbihiZXRhX0RTKSwgRV9EUz0gbWVhbihFX0RTKSwNCiAgICAgICAgICAgICAgICAgICAgRGVubGl0aCA9IG1lYW4gKERlbmxpdGgpLCBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgDQogICAgICAgICAgICAgICAgICAgIGJldGFfRFNfbGl0aD1tZWFuIChiZXRhX0RTX2xpdGgpLCBFX0RTX2xpdGg9bWVhbiAoRV9EU19saXRoKSkNCg0Kc3VtbWFyeV9EU19ieWdyb3VwIDwtIGRkcGx5KFBJQyAlPiUgZmlsdGVyICghIGdyb3VwMiAlaW4lIGMoIm5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4iKSkgLCAuKGdyb3VwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXplLCAgUElDcGVyY2VsbHBnPW1lYW4oUElDcGVyY2VsbHBnKSwgcGVybGl0aHBnID0gbWVhbihwZXJsaXRocGcpLCANCiAgICAgICAgICAgICAgICAgICAgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLCBTaW5rVmVsPW1lYW4oU2lua1ZlbCksYmV0YV9EUz1tZWFuKGJldGFfRFMpLCBFX0RTPSBtZWFuKEVfRFMpLA0KICAgICAgICAgICAgICAgICAgICBEZW5saXRoID0gbWVhbiAoRGVubGl0aCksIFNpbmtWZWxfbGl0aD1tZWFuIChTaW5rVmVsX2xpdGgpLCANCiAgICAgICAgICAgICAgICAgICAgYmV0YV9EU19saXRoPW1lYW4gKGJldGFfRFNfbGl0aCksIEVfRFNfbGl0aD1tZWFuIChFX0RTX2xpdGgpKQ0Kc3VtbWFyeV9EUw0Kc3VtbWFyeV9EU19ieWdyb3VwMg0Kc3VtbWFyeV9EU19ieWdyb3VwDQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCnJlcXVpcmUob3Blbnhsc3gpDQp3cml0ZS54bHN4KHN1bW1hcnlfRFMsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTLnhsc3giKQ0Kd3JpdGUueGxzeChzdW1tYXJ5X0RTX2J5Z3JvdXAsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTX2J5Z3JvdXAueGxzeCIpDQp3cml0ZS54bHN4KHN1bW1hcnlfRFNfYnlncm91cDIsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTX2J5Z3JvdXAyLnhsc3giKQ0KYGBgDQoNCmBgYHtyfQ0KIzguIHJlZ3Jlc3Npb25zDQojOGEuIFBJQyBhbmQgYmV0YV9EUyBvZiBjZWxscyANClBJQ19iZXRhX3JlZyA8LSBsbSAoYmV0YV9EUyB+IFBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpzdW1tYXJ5KFBJQ19iZXRhX3JlZykNCnBsb3QocmVzaWR1YWxzLmxtKFBJQ19iZXRhX3JlZykpDQpjb2VmKFBJQ19iZXRhX3JlZykNCmNvcihQSUMkUElDcGVyY2VsbHBnLCBQSUMkYmV0YV9EUykNCg0KIzhiLiBQSUMgYW5kIGJldGFfRFMgb2YgbGl0aHMNClBJQ2xpdGhfYmV0YV9yZWcgPC0gbG0gKGJldGFfRFNfbGl0aCB+IHBlcmxpdGhwZywgZGF0YT1QSUMpDQpzdW1tYXJ5KFBJQ2xpdGhfYmV0YV9yZWcpDQpwbG90KHJlc2lkdWFscy5sbShQSUNsaXRoX2JldGFfcmVnKSkNCmNvZWYoUElDbGl0aF9iZXRhX3JlZykNCmNvcihQSUMkcGVybGl0aHBnLCBQSUMkYmV0YV9EU19saXRoKQ0KDQojOGMuIGZvciBQSUMgb2YgbGl0aHMgZGVwZW5kaW5nIG9uIFBJQ3Mgb2YgY2VsbHMNClBJQ19saXRoX3JlZyA8LSBsbSAocGVybGl0aHBnflBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpzdW1tYXJ5KFBJQ19saXRoX3JlZykNCnBsb3QocmVzaWR1YWxzLmxtKFBJQ19saXRoX3JlZykpDQpjb2VmKFBJQ19saXRoX3JlZykNCmNvcihQSUMkcGVybGl0aHBnLCBQSUMkU2lua1ZlbF9saXRoKQ0KDQojOGQgb3RoZXIgcmVncmVzc2lvbnMsIGNoYW5nZSB0aGlzDQpQSUNfRGVuX2NlbGx0b3RhbF9yZWcgPC0gbG0oRGVuX2NlbGx0b3RhbCB+IFBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpQSUNfU2lua1ZlbF9yZWcgPC0gbG0gKFNpbmtWZWwgfiBQSUNwZXJjZWxscGcsIGRhdGE9UElDKQ0KUElDX0RlbmxpdGhfcmVnIDwtIGxtKERlbmxpdGggfiBwZXJsaXRocGcsIGRhdGE9UElDKQ0KUElDX1NpbmtWZWxfbGl0aF9yZWcgPC0gbG0gKFNpbmtWZWxfbGl0aCB+IFBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpwbG90KHJlc2lkdWFscy5sbShQSUNfRGVuX2NlbGx0b3RhbF9yZWcpKQ0KcGxvdChyZXNpZHVhbHMubG0oUElDX1NpbmtWZWxfcmVnKSkNCnBsb3QocmVzaWR1YWxzLmxtKFBJQ19EZW5saXRoX3JlZykpDQpwbG90KHJlc2lkdWFscy5sbShQSUNfU2lua1ZlbF9saXRoX3JlZykpDQpgYGANCg0KYGBge3J9DQojOS4gbWFrZSBhIHByZWRpY3Rpb24gYmFzZWQgb24gUElDIHZhbHVlcw0KIzlhLiBmb3IgY2VsbHMNCnJlcXVpcmUodHJ1bmNub3JtKQ0KcmVxdWlyZShSbWlzYykNCnN1bW1hcnkoUElDJFBJQ3BlcmNlbGxwZykNCnN1bW1hcnlTRShkYXRhPVBJQywgbWVhc3VyZXZhcj0iUElDcGVyY2VsbHBnIikNCg0KI21ha2UgbmV3IGRhdGFmcmFtZQ0KUElDX25ld2RhdGEgPC0gYXMuZGF0YS5mcmFtZShydHJ1bmNub3JtKG49MTAwMDAsIGE9LTAuNCwgYj0yMC4yLCBtZWFuPTUuNywgc2Q9Ni41KSkNCiNyZW5hbWUgY29sdW1uLiByZW5hbWUgZnVuY3Rpb24gaW4gcGx5ciANCmxpYnJhcnkocGx5cikNClBJQ19uZXdkYXRhIDwtIHJlbmFtZSAoUElDX25ld2RhdGEsIGMgKCJydHJ1bmNub3JtKG4gPSAxMDAwMCwgYSA9IC0wLjQsIGIgPSAyMC4yLCBtZWFuID0gNS43LCBzZCA9IDYuNSkiID0gDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQSUNwZXJjZWxscGciKSkNClBJQ19uZXdkYXRhIDwtIG11dGF0ZShQSUNfbmV3ZGF0YSwgZ3JvdXAgPSBpZmVsc2UoUElDcGVyY2VsbHBnIDwgNCAsICJuYWtlZCIsICJjYWxjaWZpZWQiKSkNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1ncm91cCwgeT1QSUNwZXJjZWxscGcpKSArIGdlb21fYm94cGxvdCgpK2dlb21fcG9pbnQoc2l6ZT0yKSArDQogICAgICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCmBgYA0KYGBge3J9DQpQSUNfbmV3ZGF0YSRncm91cDIgPC0gY2FzZV93aGVuKA0KICBQSUNfbmV3ZGF0YSRQSUNwZXJjZWxscGcgPDIgIH4gIm5ha2VkIiwNCiAgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnID4yICYgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnIDwgNCB+ICJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIiwNCiAgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnID40ICYgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnIDwgMTAgfiAibW9kZXJhdGVseSBjYWxjaWZpZWQiLA0KICBQSUNfbmV3ZGF0YSRQSUNwZXJjZWxscGcgPjEwIH4gImhlYXZpbHkgY2FsY2lmaWVkIiwgDQogIFRSVUUgfiBhcy5jaGFyYWN0ZXIoUElDX25ld2RhdGEkUElDcGVyY2VsbHBnKQ0KKQ0KDQpQSUNfbmV3ZGF0YSRncm91cDIgPC0gZmFjdG9yIChQSUNfbmV3ZGF0YSRncm91cDIsbGV2ZWxzPSBjKCJuYWtlZCIsICJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibW9kZXJhdGVseSBjYWxjaWZpZWQiLCAiaGVhdmlseSBjYWxjaWZpZWQiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJuYWtlZCIsICJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtb2RlcmF0ZWx5IGNhbGNpZmllZCIsICJoZWF2aWx5IGNhbGNpZmllZCIpKQ0KDQpnZ3Bsb3RseShnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9Z3JvdXAyLCB5PVBJQ3BlcmNlbGxwZykpICsgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpDQogICAgICAgICArdGhlbWVfUHVibGljYXRpb24oKSkNCg0KI21ha2UgbmV3IHByZWRpY3Rpb25zLiBkZW5zaXR5LCBzaW5rdmVsLCBiZXRhIGFyZSBwcmVkaWN0ZWQgYmFzZWQgb24gUElDLiBmb3IgbGl0aHMsIFBJQyBhcmUgZmlyc3QgcHJlZGljdGVkIGFuZCB0aGVuIHRoZSBvdGhlciBwYXJhbWV0ZXJzLg0KUElDX25ld2RhdGEkcGVybGl0aHBnIDwtIHByZWRpY3QoUElDX2xpdGhfcmVnLCBkYXRhLmZyYW1lKFBJQ19uZXdkYXRhKSkNClBJQ19uZXdkYXRhJERlbl9jZWxsdG90YWwgPC0gcHJlZGljdCAoUElDX0Rlbl9jZWxsdG90YWxfcmVnLCBkYXRhLmZyYW1lIChQSUNfbmV3ZGF0YSkpDQpQSUNfbmV3ZGF0YSRTaW5rVmVsIDwtIHByZWRpY3QgKFBJQ19TaW5rVmVsX3JlZywgZGF0YS5mcmFtZSAoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGEkRGVubGl0aCA8LSBwcmVkaWN0IChQSUNfRGVubGl0aF9yZWcsIGRhdGEuZnJhbWUgKFBJQ19uZXdkYXRhKSkNClBJQ19uZXdkYXRhJFNpbmtWZWxfbGl0aCA8LSBwcmVkaWN0IChQSUNfU2lua1ZlbF9saXRoX3JlZywgZGF0YS5mcmFtZSAoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGEkYmV0YV9EUyA8LSBwcmVkaWN0IChQSUNfYmV0YV9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGEkYmV0YV9EU19saXRoIDwtIHByZWRpY3QgKFBJQ2xpdGhfYmV0YV9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KDQpnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSAlPiUgZmlsdGVyICghKGdyb3VwICVpbiUgYygibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIpKSksIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1iZXRhX0RTLCBjb2xvcj0gZ3JvdXAyKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbihiZXRhfigiRW5jb3VudGVycyJ+Y21eM35kYXleLTEpKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+Y2VsbF4tMSkpICArDQogIHNjYWxlX3lfbG9nMTAoDQogICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpKw0KICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSANCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEsIGFlcyh4PXBlcmxpdGhwZywgeT1iZXRhX0RTX2xpdGgsIGNvbG9yPSBncm91cDIpKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKGJldGF+KCJFbmNvdW50ZXJzIn5jbV4zfmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIHBnIn5saXRoXi0xKSkgICsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTIpLA0KICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikrDQogIHRoZW1lKGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsIGxlZ2VuZC5ib3ggPSAidmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpIA0KDQpnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSAlPiUgZmlsdGVyIChncm91cCAlaW4lIGMoImNhbGNpZmllZCIpKSwgYWVzKHg9cGVybGl0aHBnLCB5PWJldGFfRFNfbGl0aCwgY29sb3I9IGdyb3VwMikpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oYmV0YX4oIkVuY291bnRlcnMifmNtXjN+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmxpdGheLTEpKSAgKw0KICBzY2FsZV95X2xvZzEwKA0KICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKSsNCiAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgDQoNCg0KDQpgYGANCg0KYGBge3J9DQojMTAuIGNhbGN1bGF0ZSBlbmNvdW50ZXJzIGJhc2VkIG9uIG5ld2RhdGENCiNjaGFuZ2UgdG8gdHJpbQ0KUElDX25ld2RhdGEudHJpbSRFX0RTIDwtIChQSUNfbmV3ZGF0YS50cmltJGJldGFfRFMqVmlOdW0pICNFIGNhbGN1bGF0ZWQgd2l0aCBWaXJ1cyBmb3IgY2VsbA0KUElDX25ld2RhdGEudHJpbSRFX0RTX2xpdGggPC0gKFBJQ19uZXdkYXRhLnRyaW0kYmV0YV9EU19saXRoKlZpTnVtKSAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgZm9yIGNlbGwNCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEudHJpbSwgYWVzKHg9UElDcGVyY2VsbHBnLCB5PUVfRFMpKSArZ2VvbV9wb2ludChzaXplPTUsIGFlcyhjb2xvcj1ncm91cDIpKSArDQogICAgdGhlbWVfUHVibGljYXRpb24oKSArIGdlb21fc21vb3RoKCkgKw0KICAgIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikgKw0KICAgIGxhYnMoeSA9IGV4cHJlc3Npb24oInZpcmFsIGVuY291bnRlcnMgIiB+IGRheV4tMX5jZWxsXi0xKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+Y2VsbF4tMSkpICsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXAyX3ByZWQgPC1kZHBseShQSUMsIC4oZ3JvdXAyKSwgc3VtbWFyaXplLCAgUElDcGVyY2VsbHBnPW1lYW4oUElDcGVyY2VsbHBnKSwgDQogICAgICAgICAgICAgICAgICAgIHBlcmxpdGhwZyA9IG1lYW4ocGVybGl0aHBnKSwgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLA0KICAgICAgICAgICAgICAgICAgICBTaW5rVmVsPW1lYW4oU2lua1ZlbCksYmV0YV9EUz1tZWFuKGJldGFfRFMpLCBFX0RTPSBtZWFuKEVfRFMpLCANCiAgICAgICAgICAgICAgICAgICAgRGVubGl0aCA9IG1lYW4gKERlbmxpdGgpLCBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgDQogICAgICAgICAgICAgICAgICAgIGJldGFfRFNfbGl0aD1tZWFuIChiZXRhX0RTX2xpdGgpLCBFX0RTX2xpdGg9bWVhbiAoRV9EU19saXRoKSkNCnN1bW1hcnlfRFNfYnlncm91cDJfcHJlZA0KDQojcmVtb3ZlIG5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4NCg0Kc3VtbWFyeV9EU19ieWdyb3VwX3ByZWQgPC1kZHBseShQSUNfbmV3ZGF0YS50cmltLCAuKGdyb3VwKSwgc3VtbWFyaXplLCAgUElDcGVyY2VsbHBnPW1lYW4oUElDcGVyY2VsbHBnKSwgDQogICAgICAgICAgICAgICAgICAgIHBlcmxpdGhwZyA9IG1lYW4ocGVybGl0aHBnKSwgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLA0KICAgICAgICAgICAgICAgICAgICBTaW5rVmVsPW1lYW4oU2lua1ZlbCksYmV0YV9EUz1tZWFuKGJldGFfRFMpLCBFX0RTPSBtZWFuKEVfRFMpLCANCiAgICAgICAgICAgICAgICAgICAgRGVubGl0aCA9IG1lYW4gKERlbmxpdGgpLCBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgDQogICAgICAgICAgICAgICAgICAgIGJldGFfRFNfbGl0aD1tZWFuIChiZXRhX0RTX2xpdGgpLCBFX0RTX2xpdGg9bWVhbiAoRV9EU19saXRoKSkNCnN1bW1hcnlfRFNfYnlncm91cF9wcmVkDQoNCmdncGxvdChkYXRhPVBJQ19uZXdkYXRhLnRyaW0sIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1FX0RTKSkgK2dlb21fcG9pbnQoc2l6ZT01LCBhZXMoY29sb3I9Z3JvdXAyKSkgKw0KICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyBnZW9tX3Ntb290aCgpICsNCiAgICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpICsNCiAgICBsYWJzKHkgPSBleHByZXNzaW9uKCJ2aXJhbCBlbmNvdW50ZXJzICIgfiBkYXleLTF+Y2VsbF4tMSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmNlbGxeLTEpKSArDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEudHJpbSwgYWVzKHg9cGVybGl0aHBnLCB5PUVfRFMpKSArZ2VvbV9wb2ludChzaXplPTUsIGFlcyhjb2xvcj1ncm91cDIpKSArDQogICAgdGhlbWVfUHVibGljYXRpb24oKSArIGdlb21fc21vb3RoKCkgKw0KICAgIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikgKw0KICAgIGxhYnMoeSA9IGV4cHJlc3Npb24oInZpcmFsIGVuY291bnRlcnMgIiB+IGRheV4tMX5saXRoXi0xKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+bGl0aF4tMSkpICsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KDQoNCnNldHdkKCJEOi9SIHByb2dyYW0iKQ0Kd3JpdGUueGxzeChzdW1tYXJ5X0RTX2J5Z3JvdXBfcHJlZCwgZmlsZSA9ICJQb3N0ZG9jLVIvRXhwb3J0ZWQgVGFibGVzL3N1bW1hcnlfRFNfYnlncm91cF9wcmVkLnhsc3giKQ0KYGBgDQoNCmBgYHtyfQ0KI2FycmFuZ2UgdGhlIHN1bW1hcnkNCkRTX3ByZWQgPC0gZGF0YS5mcmFtZSAoZ3JvdXA9YXMuZmFjdG9yKGMoIk5jIiwgIkNjIiwgIkxpIikpLCByYWQ9IGMoMS44RS02LCAyLjNFLTYsIDEuNUUtNiksIA0KICAgICAgICAgICAgICAgICAgUElDPSBjKDAuODI5NjM4MiwgOS42MDMyNjQ0LCAwLjQ4MDE2MzIyKSwgRGVuPSBjKDEuMDg3MDU4LCAxLjI0ODIyNiwgMS4yMTAwNTQpLA0KICAgICAgICAgICAgICAgICAgU2lua1ZlbCA9IGMoMC4wMzM3NzkxMywgMC4xODgzMjMzMCwgMC4wNDgzNjcyNCksIA0KICAgICAgICAgICAgICAgICAgYmV0YV9EUyA9IGMoMy44MTU5ODNlLTA3LCAzLjI4MTY1N2UtMDYsIDIuNzI4NDE3ZS0wNykpDQoNCkRTIDwtIGRhdGEuZnJhbWUgKGdyb3VwPWFzLmZhY3RvcihjKCJOYyIsICJDYyIsICJMaSIpKSwgcmFkPSBjKDEuOEUtNiwgMi4zRS02LCAxLjVFLTYpLA0KICAgICAgICAgICAgICAgICAgUElDID0gYygwLjY5NzkyMjIsIDExLjQ4NDAxMTksIDAuNTc0MjAwNTkpLCBEZW4gPSBjKDEuMDc4NTY5LCAxLjI3NTMzMSwgMS4yNDE0MDApLA0KICAgICAgICAgICAgICAgICAgU2lua1ZlbCA9IGMgKDAuMDI5MDMzMTEsIDAuMjIxNTE0NywgMC4wNTY1NjAwMiksIA0KICAgICAgICAgICAgICAgICAgYmV0YV9EUyA9IGMoMy4yNTgxMTllLTA3LCAzLjk3NTEwM2UtMDYsIDMuMTkwNTc1ZS0wNykpDQoNCkRTDQpEU19wcmVkDQpgYGANCg0KVHVyYnVsZW5jZQ0KYGBge3J9DQojVHVyYnVsZW5jZQ0KIzEuIG1ha2UgbmV3IGRhdGFmcmFtZQ0KI2Rpc3JhdGUgaXMgY20yL3MzDQojbWFrZSBkYXRhIGZyYW1lDQpkaXNyYXRlIDwtIHJlcF9sZW4gKGMgKDEgJW8lIDEwXihzZXEoLTgsLTIsIDAuNSkpKSwgbGVuZ3RoLm91dD0zOSkNCmNhbGMgPC0gcmVwX2xlbihjKCJDYyIpLCBsZW5ndGgub3V0PTEzKQ0KbmFrZWQgPC0gcmVwX2xlbihjKCJOYyIpLCBsZW5ndGgub3V0PTEzKQ0KbGl0aCA8LSByZXBfbGVuKGMoIkxpIiksIGxlbmd0aC5vdXQ9MTMpDQpncm91cCA8LSBjKG5ha2VkLCBjYWxjLCBsaXRoKQ0KdHVyYiA8LSBhcy5kYXRhLmZyYW1lKGNiaW5kKGRpc3JhdGUsIGdyb3VwKSkNCg0KdHVyYiRyYWQgPC0gY2FzZV93aGVuKA0KICAgIHR1cmIkZ3JvdXAgPT0iTmMiIH4gMS44RS02LA0KICAgIHR1cmIkZ3JvdXAgPT0iQ2MiIH4gMi4zRS02LA0KICAgIHR1cmIkZ3JvdXAgPT0iTGkiIH4gMS4yNUUtNiwNCiAgICBUUlVFIH4gYXMubnVtZXJpYyh0dXJiJGdyb3VwKQ0KKQ0KdHVyYiRkaXNyYXRlIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHR1cmIkZGlzcmF0ZSkpDQoNCiMyLiBjYWxjdWxhdGUgYmV0YSBhbmQgZW5jb3VudGVycw0KdHVyYiRiZXRhX3R1cmIgPC0gKDQuMipwaSooKHR1cmIkZGlzcmF0ZS8odioxMDBeMikpXjAuNSkqKCgodHVyYiRyYWQrUmVodikqMTAwKV4zKSkqODY0MDAgDQp0dXJiJEVfdHVyYiA8LSAodHVyYiRiZXRhX3R1cmIqdmlybnVtKSAjRSBjYWxjdWxhdGVkIHdpdGggdmlydXMgb25seQ0KDQp0dXJiJGdyb3VwIDwtIGZhY3RvciAodHVyYiRncm91cCxsZXZlbHM9IGMoIk5jIiwgIkNjIiwgIkxpIiksIGxhYmVscyA9IGMoIk5jIiwgIkNjIiwgIkxpIikpDQoNCmdncGxvdChkYXRhID0gdHVyYiwgYWVzKHggPSBkaXNyYXRlLCB5ID0gYmV0YV90dXJiLCBjb2xvcj1ncm91cCkpICsgZ2VvbV9wb2ludChzaXplID01KSArDQogIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBzY2FsZV94X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgYW5ub3RhdGlvbl9sb2d0aWNrcygpICsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oYmV0YX4oInByZWRpY3RlZCBlbmNvdW50ZXJzICIgfmNtXjN+ZGF5Xi0xKSksIA0KICAgICAgIHggPSBleHByZXNzaW9uKCJkaXNzaXBhdGlvbiByYXRlICJ+KG1eMn5zXi0zKSkpICsNCiAgIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KZ2dwbG90KGRhdGEgPSB0dXJiLCBhZXMoeCA9IGRpc3JhdGUsIHkgPSBFX3R1cmIsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX3BvaW50KHNpemUgPTUpICsNCiAgIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBzY2FsZV94X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTcpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgYW5ub3RhdGlvbl9sb2d0aWNrcygpKw0KICB0aGVtZV9QdWJsaWNhdGlvbigpKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKCJ2aXJhbCBlbmNvdW50ZXJzICIgfiBjbV4tM35kYXleLTEpLHggPSBleHByZXNzaW9uKCJkaXNzaXBhdGlvbiByYXRlICJ+KG1eMn5zXi0zKSkpICsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCm1lbHQgYWxsIGRhdGEgYW5kIG1ha2UgYSB0YWJsZSB3aXRoIGFsbA0KYGBge3J9DQphbGwgPC0gUmVkdWNlKGZ1bmN0aW9uKHgseSkgbWVyZ2UoeCx5LGJ5PSJncm91cCIsYWxsPVRSVUUpICwNCiAgICAgICAgICAgICAgbGlzdChCTSAlPiUgc2VsZWN0IChncm91cCwgYmV0YV9CTSksIERTX3ByZWQgJT4lIHNlbGVjdCAoZ3JvdXAsIGJldGFfRFMpLCANCiAgICAgICAgICAgICAgICAgICB0dXJiICU+JSBzZWxlY3QgKGdyb3VwLCBkaXNyYXRlLCBiZXRhX3R1cmIpKSkNCmFsbCRiZXRhX2FsbCA8LSBhbGwkYmV0YV9CTSArIGFsbCRiZXRhX0RTICsgYWxsJGJldGFfdHVyYg0KYWxsJEVfYWxsX2xvdyA8LSBhbGwkYmV0YV9hbGwqKDEwXjQpDQphbGwkRV9hbGxfaGlnaCA8LSBhbGwkYmV0YV9hbGwqKDEwXjYpDQphbGwkZ3JvdXAgPC0gZmFjdG9yIChhbGwkZ3JvdXAsbGV2ZWxzPSBjKCJOYyIsICJDYyIsICJMaSIpLCBsYWJlbHMgPSBjKCJOYyIsICJDYyIsICJMaSIpKQ0KDQoNCiNwbG90dGluZw0KZ2dwbG90KGRhdGE9YWxsLCBhZXMoeD1kaXNyYXRlLHkgPSBFX2FsbF9sb3csIGNvbG9yPWdyb3VwKSkgKyANCiAgZ2VvbV9saW5lKHNpemU9MSwgcG9zaXRpb249cG9zaXRpb25faml0dGVyKHc9MC4wMiwgaD0wKSwgYWVzKGxpbmV0eXBlPSIxMF4zIikpKw0KICBnZW9tX2xpbmUoZGF0YSA9IGFsbCwgYWVzKHk9IEVfYWxsX2hpZ2gsIGNvbG9yPWdyb3VwLCBsaW5ldHlwZT0iMTBeNSIpKSArDQogICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTIpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj03KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmtleS53aWR0aD11bml0KDEsImNtIikpKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKCJ2aXJhbCBlbmNvdW50ZXJzICIgfmRheV4tMX5jZWxsXi0xKSwgeCA9IGV4cHJlc3Npb24oImRpc3NpcGF0aW9uIHJhdGUgIn4obV4yfnNeLTMpKSkgKw0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQpgYGANCg0K